package com.wtpaint.lib.skin;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;

/**
 * Created by leoxu on 2018/11/18.
 */

public class ZeusSkinFactory implements LayoutInflater.Factory2, Observer {

    private static final String[] mClassPrefixList = {
            "android.widget.",
            "android.view.",
            "android.webkit."
    };

    private static final Class<?>[] mConstructorSignature = new Class[]{
            Context.class, AttributeSet.class};

    private static final HashMap<String, Constructor<? extends View>> sConstructorMap = new HashMap<>();

    private ZeusAttribute skinAttribute;

    public ZeusSkinFactory() {
        skinAttribute = new ZeusAttribute();
    }


    @Override
    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        // name xml中标签名称
        View view = createViewFromXML(name, context, attrs);
        if (null == view) {
            view = createView(name, context, attrs);
        }
        skinAttribute.load(view, attrs);
        return view;
    }

    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        return null;
    }

    private View createViewFromXML(String name, Context context, AttributeSet attrs) {
        if (name.contains(".")) {//com.xx.MyImageView 自定义控件
            return null;
        }
        View view = null;
        for (String aMClassPrefixList : mClassPrefixList) {
            view = createView(aMClassPrefixList + name, context, attrs);
            if (null != view) {
                break;
            }
        }
        return view;

    }

    private View createView(String name, Context context, AttributeSet attrs) {

        Constructor<? extends View> constructor = sConstructorMap.get(name);
        if (null == constructor) {
            try {
                Class<? extends View> subClass = context.getClassLoader().loadClass(name).asSubclass(View.class);
                constructor = subClass.getConstructor(mConstructorSignature);
                sConstructorMap.put(name, constructor);

            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        if (null != constructor) {
            try {
                return constructor.newInstance(context, attrs);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    @Override
    public void update(Observable o, Object arg) {
        skinAttribute.applySkin();
    }
}
